﻿using System;
using System.Reflection;

namespace Dotnet.Utils.Utility.AssemblyUtil
{
    public class ReflectionUtil
    {
        public static Type ReflectType(string typeName, Assembly ass = null)
        {
            Type type;
            if (ass == null)
            {
                type = Type.GetType(typeName);
            }
            else
            {
                type = ass.GetType(typeName);
            }
            if (type == null)
            {
                throw new Exception("没有找到类" + typeName + "，无法初始化该类型！");
            }
            return type;
        }

        public static object ReflectTypeInstence(string typeName, Assembly ass = null, params object[] prms)
        {
            Type type;
            if (ass == null)
            {
                type = Type.GetType(typeName);
            }
            else
            {
                type = ass.GetType(typeName);
            }
            if (type == null)
            {
                throw new Exception("没有找到类" + typeName + "，无法初始化该类型！");
            }
            object result;
            if (prms == null)
            {
                result = Activator.CreateInstance(type);
            }
            else
            {
                result = Activator.CreateInstance(type, prms);
            }
            return result;
        }

        public static T ReflectTypeInstence<T>(string typeName, Assembly ass = null, params object[] prms)
        {
            Type type;
            if (ass == null)
            {
                type = Type.GetType(typeName);
            }
            else
            {
                type = ass.GetType(typeName);
            }
            if (type == null)
            {
                throw new Exception("没有找到类" + typeName + "，无法初始化该类型！");
            }
            T result;
            if (prms == null)
            {
                result = (T)((object)Activator.CreateInstance(type));
            }
            else
            {
                result = (T)((object)Activator.CreateInstance(type, prms));
            }
            return result;
        }

        public static object ReflectTypeSingleton(string typeName, string singletonPropertyName = "Instance", Assembly ass = null)
        {
            Type type = ReflectionUtil.ReflectType(typeName, ass);
            object result;
            try
            {
                object obj = type.GetProperty(singletonPropertyName).GetValue(null, null);
                result = obj;
            }
            catch
            {
                object obj = Activator.CreateInstance(type);
                result = obj;
            }
            return result;
        }

        public static T ReflectTypeSingleton<T>(string typeName, string singletonPropertyName = "Instance", Assembly ass = null) where T : class
        {
            Type type = ReflectionUtil.ReflectType(typeName, ass);
            T result;
            try
            {
                T t = type.GetProperty(singletonPropertyName).GetValue(null, null) as T;
                result = t;
            }
            catch
            {
                T t = Activator.CreateInstance(type) as T;
                result = t;
            }
            return result;
        }

        public static void InvokeStaticMethod(string typeName, string methodName, params object[] pars)
        {
            Type type = ReflectionUtil.ReflectType(typeName, null);
            ReflectionUtil.InvokeStaticMethod(type, methodName, pars);
        }

        public static void InvokeStaticMethod(Type type, string methodName, params object[] pars)
        {
            MethodInfo method = type.GetMethod(methodName);
            method.Invoke(null, pars);
        }
    }
}